Design - Architecture Patterns
About
-
Set of structures needed to reason about a software system.
-
It is about making fundamental structural choices that are costly to change once implemented.
-
Used to extrapolate the tasks that need to be executed by the teams and people involved.
-
Software architecture patterns operate at a higher level of abstraction than software design patterns, solving broader system-level challenges.
-
While these patterns typically affect system-level concerns, the distinction between architectural patterns and architectural styles can sometimes be blurry.
-
Chat-GPT: Depending on the scope of the use of a strategy, it can be seen as a Design Pattern or as a Software Architecture. It depends on the scope and impact of its use.
Component-Based Architecture (CBA) / Component Pattern
-
Component Pattern / Strategy Pattern.
Application: Functional Programming
-
Without classes :
// Components defined as types (immutable types) type Position = { x: number, y: number }; type Velocity = { dx: number, dy: number }; // Entity composed of components type Entity = { position: Position, velocity: Velocity }; // System that updates the position of an entity function updatePosition(entity: Entity): Entity { const newPosition = { x: entity.position.x + entity.velocity.dx, y: entity.position.y + entity.velocity.dy }; return { ...entity, position: newPosition }; } // Creating an entity with components const player: Entity = { position: { x: 0, y: 0 }, velocity: { dx: 2, dy: 3 } }; // Updating the position const newPlayer = updatePosition(player); console.log(newPlayer.position); // { x: 2, y: 3 } -
With classes :
// Defining components as classes class Position { constructor(public readonly x: number, public readonly y: number) {} // Method to update position update(dx: number, dy: number): Position { return new Position(this.x + dx, this.y + dy); } } class Velocity { constructor(public readonly dx: number, public readonly dy: number) {} } // Entity composed of components (using composition) class Entity { constructor( public readonly position: Position, public readonly velocity: Velocity ) {} // Method to update entity position updatePosition(): Entity { const newPosition = this.position.update(this.velocity.dx, this.velocity.dy); return new Entity(newPosition, this.velocity); } } // Creating an entity with components const player = new Entity(new Position(0, 0), new Velocity(2, 3)); // Updating the position const newPlayer = player.updatePosition(); console.log(newPlayer.position); // Position { x: 2, y: 3 }
Application: OOP
// Components defined as classes
class Position {
constructor(public x: number, public y: number) {}
}
class Velocity {
constructor(public dx: number, public dy: number) {}
}
// Entity that stores components (composition)
class Entity {
components: { [key: string]: any } = {};
addComponent(name: string, component: any) {
this.components[name] = component;
}
getComponent(name: string) {
return this.components[name];
}
}
// System that updates the position of an entity
function updatePosition(entity: Entity) {
const position = entity.getComponent("position");
const velocity = entity.getComponent("velocity");
if (position && velocity) {
position.x += velocity.dx;
position.y += velocity.dy;
}
}
// Creating an entity and adding components
const player = new Entity();
player.addComponent("position", new Position(0, 0));
player.addComponent("velocity", new Velocity(2, 3));
updatePosition(player);
console.log(player.getComponent("position")); // { x: 2, y: 3 }
ECS (Entity Component System)
MVC (Model View Controller)
-
Low-level.
-
Ruby on rails.
-
Used in WebDev.
Opnions I saw about it
-
"It seems like everything goes inside the Controller, it's strange".
CQRS (Command Query Responsibility Segregation) + ES (Event Sourcing)
-
Separation of responsibilities, I donβt know.